package com.mini.service;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.mini.conditon.*;
import com.mini.constant.RedisKeyConst;
import com.mini.model.BusinessBelongingInfo;
import com.mini.model.BusinessGroupBase;
import com.mini.model.BusinessRangeInfo;
import com.mini.vo.DeptVO;
import com.mini.vo.PageResultVO;
import com.mini.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author: zhaocg
 * @created: 2020/12/02 12:03
 */
@Slf4j
@Service
public class BusinessGroupManagerService extends BaseService{

    @Autowired
    private BusinessGroupBaseService groupBaseService;

    @Autowired
    private BusinessBelongingInfoService belongingInfoService;

    @Autowired
    private BusinessRangeInfoService rangeInfoService;

    @Autowired
    private DictionariesBaseService dictionariesBaseService;

    @Autowired
    private InnerOperationRecordService operationRecordService;



    /**
     * 业务组查询接口-分页
     *
     * @param condition
     * @return
     */
    public PageResultVO<BusinessGroupBase> groupBasePageList(GroupManagerQueryCondition condition){

        long startTime = System.currentTimeMillis();
        PageResultVO<BusinessGroupBase> resultVO = new PageResultVO<>();

        // 设置业务组ID
        setBusinessGroupIdList(condition);

        if (StringUtils.isNotBlank(condition.getKeyWord()) && !CollectionUtils.isEmpty(condition.getIdList())) {
            if (condition.getIdList().contains(condition.getKeyWord())) {
                condition.setIdList(null);
            }
        }
        log.info("set param condition={}" , JSONObject.toJSONString(condition));

        Page<BusinessGroupBase> page = groupBaseService.groupPageList(condition);
        if (page != null && !CollectionUtils.isEmpty(page.getContent())) {
            List<BusinessGroupBase> groupBaseList = page.getContent();
            log.info("条数count={}" , groupBaseList.size());
            groupBaseList.stream().forEach(groupBase -> {
                Long businessGroupId = groupBase.getId();
                // 业务范围--控制显示条数，并设置业务范围数据
                Long rangeCount = rangeInfoService.countByBusinessGroupId(businessGroupId);
                if (rangeCount != null && rangeCount.intValue() > 2) {
                    List<BusinessRangeInfo> rangeInfoList = rangeInfoService.findByGroupId(businessGroupId);
                    groupBase.setRangeInfoList(rangeInfoList);
                    groupBase.setRangeInfo(true);
                } else {
                    RangeInfoCondition rangeInfoCondition = new RangeInfoCondition();
                    rangeInfoCondition.setBusinessGroupId(businessGroupId);
                    groupBase.setRangeInfoList(rangeInfoService.rangeInfoList(rangeInfoCondition));
                    groupBase.setRangeInfo(false);
                }
                // 业务所属组--控制显示条数，并设置业务所属组数据
                Long belongingCount = belongingInfoService.countByBusinessGroupId(businessGroupId);
                if (belongingCount != null && belongingCount.intValue() > 2) {
                    groupBase.setBelongingInfoList(belongingInfoService.findTop2ByBusinessGroupId(businessGroupId));
                    groupBase.setBelongingInfo(true);
                } else {
                    groupBase.setBelongingInfoList(belongingInfoService.findByGroupId(businessGroupId));
                    groupBase.setBelongingInfo(false);
                }
            });
            resultVO.setRows(groupBaseList);
            resultVO.setTotal(page.getTotalElements());
        }
        long endTime = System.currentTimeMillis();
        log.info("分页查询业务组数据共用时:{}m" , (endTime-startTime) / 1000);
        return resultVO;
    }

    /**
     * 设置组织以及业务范围数据
     *
     * @param condition
     */
    private void setBusinessGroupIdList(GroupManagerQueryCondition condition){

        List<Long> groupIdList = new ArrayList<>();
        boolean flag = false;
        if (!CollectionUtils.isEmpty(condition.getOrgIds())) {
            List<String> orgStrList = condition.getOrgIds().stream().map(String::valueOf).collect(Collectors.toList());
            List<DeptVO> deptVOList = groupIdsInfo(orgStrList , condition.getUserId());
            if (!CollectionUtils.isEmpty(deptVOList)) {
                List<Long> deptIds = deptVOList.stream().map(DeptVO::getId).collect(Collectors.toList());
                BelongingInfoCondition infoCondition = new BelongingInfoCondition();
                infoCondition.setDeptIdList(deptIds);
                List<BusinessBelongingInfo> belongingInfoConditionList = belongingInfoService.belongingInfoList(infoCondition);
                if (!CollectionUtils.isEmpty(belongingInfoConditionList)) {
                    UserVO userVO = miniAdminService.getUserSimpleInfo(condition.getUserId());
                    Long odId = null;
                    if (Objects.nonNull(userVO) && Objects.nonNull(userVO.getFullDept())) {
                        odId = userVO.getFullDept().getOdId();
                    }
                    if (odId != null) {
                        List<Long> businessIdList = belongingInfoConditionList.stream().map(BusinessBelongingInfo::getBusinessGroupId).distinct().collect(Collectors.toList());
                        List<BusinessBelongingInfo> remakeBelongingList = belongingInfoService.findByBusinessGroupIdIn(businessIdList);
                        if (!CollectionUtils.isEmpty(remakeBelongingList)) {
                            Map<Long, List<BusinessBelongingInfo>> belongingInfoMap = remakeBelongingList.stream().collect(Collectors.groupingBy(BusinessBelongingInfo::getBusinessGroupId));
                            //遍历分组
                            for (Map.Entry<Long, List<BusinessBelongingInfo>> belongingInfo : belongingInfoMap.entrySet()) {
                                Long key = belongingInfo.getKey();
                                List<BusinessBelongingInfo> entryBelongingList = belongingInfo.getValue();
                                if (!CollectionUtils.isEmpty(entryBelongingList)) {
                                    List<Long> remakeDeptIds = new ArrayList<>();
                                    entryBelongingList.stream().forEach(belonging -> {
                                        // 获取销售组
                                        Long deptId = belonging.getDeptId();
                                        // 根据销售组获取销售部
                                        DeptVO deptVO = miniAdminService.getParentDept(deptId);
                                        remakeDeptIds.add(deptVO.getId());
                                    });
                                    long count = remakeDeptIds.stream().distinct().count();
                                    if (count == 1) {
                                        groupIdList.add(key);
                                    }
                                }
                            }
                        }
                        if (!CollectionUtils.isEmpty(groupIdList)) {
                            condition.setIdList(groupIdList);
                        } else {
                            condition.setIdList(Lists.newArrayList(9999999999999L));
                            flag = true;
                        }
                    } else {
                        groupIdList = belongingInfoConditionList.stream().map(BusinessBelongingInfo::getBusinessGroupId).distinct().collect(Collectors.toList());
                        condition.setIdList(groupIdList);
                    }
                } else {
                    condition.setIdList(Lists.newArrayList(9999999999999L));
                    flag = true;
                }
            } else {
                condition.setIdList(Lists.newArrayList(9999999999999L));
                flag = true;
            }
        }
        if ( !flag ) {
            if (StringUtils.isNotBlank(condition.getChannelCode()) || condition.getProjectId() != null || StringUtils.isNotBlank(condition.getRegionCode())) {
                RangeInfoCondition rangeInfoCondition = new RangeInfoCondition();
                rangeInfoCondition.setChannelCode(condition.getChannelCode());
                rangeInfoCondition.setProjectId(condition.getProjectId());
                rangeInfoCondition.setRegionCode(condition.getRegionCode());
                List<BusinessRangeInfo> businessRangeInfoList = rangeInfoService.rangeInfoList(rangeInfoCondition);
                if (!CollectionUtils.isEmpty(businessRangeInfoList)) {
                    List<Long> idList = businessRangeInfoList.stream().map(BusinessRangeInfo::getBusinessGroupId).distinct().collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(groupIdList)) {
                        groupIdList.retainAll(idList);
                        if (!CollectionUtils.isEmpty(groupIdList)) {
                            condition.setIdList(groupIdList);
                        } else {
                            condition.setIdList(Lists.newArrayList(9999999999999L));
                        }
                    } else {
                        condition.setIdList(idList);
                    }
                } else {
                    condition.setIdList(Lists.newArrayList(9999999999999L));
                }
            }
        }
    }

    /**
     * 保存业务组数据
     *
     * @param condition
     */
    @Transactional
    public void save(GroupManagerCondition condition , String token){
        BusinessGroupBase businessGroupBase = new BusinessGroupBase();
        businessGroupBase.setOperatorId(condition.getOperatorId());
        businessGroupBase.setGroupName(condition.getGroupName());
        businessGroupBase = groupBaseService.save(businessGroupBase);
        Long businessGroupId = businessGroupBase.getId();

        condition.getRegionCodeList().stream().forEach(regionCode->{
            condition.getChannelCodeList().stream().forEach(channelCode->{
                condition.getProjectIdList().stream().forEach(projectId->{
                    saveRangeInfo(token ,regionCode , channelCode , projectId , businessGroupId , condition.getOperatorId());
                });
            });
        });
        // 保存所属组数据
        condition.getDeptIdList().stream().forEach(deptId->{
            saveBelongInfo(businessGroupId , deptId , condition.getOperatorId() , condition.getLegionId() , condition.getArmyId());
        });
        // 保存操作记录
        asyncTaskManager.getExecutor().submit(new Runnable() {
            @Override
            public void run() {
                operationRecordService.createBusinessGroup(condition , businessGroupId,token);
            }
        });
    }

    /**
     * 保存所属组数据
     *
     * @param businessGroupId
     * @param deptId
     * @param operatorId
     */
    private void saveBelongInfo(Long businessGroupId , Long deptId , Long operatorId , Long legionId , Long armyId){
        BusinessBelongingInfo belongingInfo = new BusinessBelongingInfo();
        belongingInfo.setBusinessGroupId(businessGroupId);
        belongingInfo.setDeptId(deptId);
        belongingInfo.setOperatorId(operatorId);
        belongingInfo.setLegionId(legionId);
        belongingInfo.setArmyId(armyId);
        belongingInfoService.save(belongingInfo);
    }

    /**
     * 保存业务范围
     *
     * @param regionCode
     * @param channelCode
     * @param projectId
     * @param businessGroupId
     * @param operatorId
     */
    private void saveRangeInfo(String token ,String regionCode , String channelCode , Long projectId ,
                               Long businessGroupId , Long operatorId){
        BusinessRangeInfo rangeInfo = new BusinessRangeInfo();
        rangeInfo.setRegionCode(regionCode);
        rangeInfo.setRegionName(dictionariesBaseService.getProvinceName(regionCode));
        rangeInfo.setChannelCode(channelCode);
        rangeInfo.setChannelName(dictionariesBaseService.getChannelName(channelCode, token));
        rangeInfo.setProjectId(projectId);
        rangeInfo.setProjectName(dictionariesBaseService.getItemName(token , projectId.intValue()));
        rangeInfo.setBusinessGroupId(businessGroupId);
        rangeInfo.setOperatorId(operatorId);
        rangeInfoService.save(rangeInfo);
    }

    /**
     * 追加业务范围
     *
     * @param condition
     * @param token
     */
    public void appendRangeInfo(AppendRangeInfoCondition condition , String token){
        condition.getRegionCodeList().stream().forEach(regionCode->{
            condition.getChannelCodeList().stream().forEach(channelCode->{
                condition.getProjectIdList().stream().forEach(projectId->{
                    saveRangeInfo(token ,regionCode , channelCode , projectId , condition.getBusinessGroupId() , condition.getOperatorId());
                });
            });
        });
        asyncTaskManager.getExecutor().submit(new Runnable() {
            @Override
            public void run() {
                BusinessGroupBase groupBase = groupBaseService.findById(condition.getBusinessGroupId());
                operationRecordService.addRangingInfo(condition ,token , groupBase.getGroupName());
            }
        });
    }

    /**
     * 删除原有销售组并重新添加
     *
     * @param condition
     */
    @Transactional
    public void updateBelongingInfo(ModifyBelongingInfoCondition condition){
        String key = RedisKeyConst.getBelongIngKey("deleteSave");
        if (tryLock(key)) {
            try {
                List<BusinessBelongingInfo> belongingInfoList = findByGroupId(condition.getBusinessGroupId());
                // 删除所有所属组
                deletedAllBelongingInfo(condition.getBusinessGroupId());
                // 保存选中所属组数据
                condition.getDeptIdList().stream().forEach(deptId -> {
                    saveBelongInfo(condition.getBusinessGroupId(), deptId, condition.getOperatorId(), condition.getLegionId(), condition.getArmyId());
                });
                if (!CollectionUtils.isEmpty(belongingInfoList)) {
                    // 保存操作记录
                    asyncTaskManager.getExecutor().submit(new Runnable() {
                        @Override
                        public void run() {
                            List<Long> oldDeptIds = belongingInfoList.stream().map(BusinessBelongingInfo::getDeptId).collect(Collectors.toList());
                            BusinessGroupBase groupBase = groupBaseService.findById(condition.getBusinessGroupId());
                            operationRecordService.addBelongingInfo(oldDeptIds , condition.getDeptIdList() , condition.getBusinessGroupId() , condition.getOperatorId() , groupBase.getGroupName());
                        }
                    });
                }
            } catch (Exception e) {
                log.error("updateBelongingInfo error={}" , e);
                releaseLockKey(key);
            } finally {
                releaseLockKey(key);
            }
        }
    }

    /**
     * 删除业务组
     *
     * @param id
     */
    @Transactional
    public void deleteGroupBase(Long id,String token){
        BusinessGroupBase businessGroupBase = groupBaseService.findById(id);
        groupBaseService.deleted(businessGroupBase);
        rangeInfoService.deletedByGroupId(id);
        deletedAllBelongingInfo(id);
        asyncTaskManager.getExecutor().submit(new Runnable() {
            @Override
            public void run() {
                operationRecordService.deletedBusinessGroup(token , id , businessGroupBase.getGroupName());
            }
        });
    }

    /**
     * 根据条件删除全部业务范围
     *
     * @param condition
     */
    @Transactional
    public void deletedAllRangeInfo(RangeInfoCondition condition ,String token){
        List<BusinessRangeInfo> businessRangeInfoList = rangeInfoService.rangeInfoList(condition);
        if (!CollectionUtils.isEmpty(businessRangeInfoList)) {
            rangeInfoService.deletedList(businessRangeInfoList);
            asyncTaskManager.getExecutor().submit(new Runnable() {
                @Override
                public void run() {
                    BusinessGroupBase groupBase = groupBaseService.findById(condition.getBusinessGroupId());
                    operationRecordService.deletedRangingInfo(businessRangeInfoList , condition.getBusinessGroupId() ,
                            token ,groupBase.getGroupName() );
                }
            });
        }
    }

    /**
     * 删除全部所属组
     *
     * @param businessId
     */
    @Transactional
    public void deletedAllBelongingInfo(Long businessId){
        belongingInfoService.deletedByGroupId(businessId);
    }

    /**
     * 删除业务范围
     *
     * @param id
     */
    public void deletedRangeInfo(Long id , String token) {
        BusinessRangeInfo rangeInfo = rangeInfoService.findById(id);
        rangeInfoService.deleted(rangeInfo);
        asyncTaskManager.getExecutor().submit(new Runnable() {
            @Override
            public void run() {
                BusinessGroupBase groupBase = groupBaseService.findById(rangeInfo.getBusinessGroupId());
                List<BusinessRangeInfo> businessRangeInfoList = new ArrayList<>();
                businessRangeInfoList.add(rangeInfo);
                operationRecordService.deletedRangingInfo(businessRangeInfoList , groupBase.getId() ,
                        token ,groupBase.getGroupName() );
            }
        });
    }

    /**
     * 删除所属组
     * @param id
     */
    public void deletedBelongingInfo(Long id){
        belongingInfoService.deleted(id);
    }

    /**
     * 获取业务范围列表（分页）
     *
     * @param condition
     * @return
     */
    public PageResultVO<BusinessRangeInfo> rangePageList(RangeInfoCondition condition){
        return rangeInfoService.pageList(condition);
    }

    /**
     * 获取所有(所属组数据)
     *
     * @param businessGroupId
     * @return
     */
    public List<BusinessBelongingInfo> findByGroupId(Long businessGroupId){
        return belongingInfoService.findByGroupId(businessGroupId);
    }

    /**
     * 根据条件--(获取所有所属组数据)
     *
     * @param condition
     * @return
     */
    public List<BusinessBelongingInfo> belongingInfoList(BelongingInfoCondition condition){
        return belongingInfoService.belongingInfoList(condition);
    }


    /**
     * 供分配使用，根据相关条件获取
     * @param condition
     * @return
     */
    public String queryOrgIdsByBusinessGroup(DistributionCondition condition){
        String deptIds = "";
        // 设置业务组ID
        setBusinessGroupIdListDistribution(condition);
        if (!CollectionUtils.isEmpty(condition.getIdList())) {
            List<BusinessBelongingInfo> belongingInfoList =
                    belongingInfoService.findByBusinessGroupIdIn(condition.getIdList());
            if (!CollectionUtils.isEmpty(belongingInfoList)) {
                deptIds = belongingInfoList
                        .stream()
                        .filter(o->o.getBusinessGroupId() != null)
                        .map(o->String.valueOf(o.getDeptId()))
                        .distinct()
                        .collect(Collectors.joining(","));
            }
        }
        return deptIds;
    }

    /**
     * 设置组织以及业务范围数据--为分配
     *
     * @param condition
     */
    private void setBusinessGroupIdListDistribution(DistributionCondition condition){
        List<Long> groupIdList = null;
        boolean flag = false;
        if (condition.getLegionId() != null) {
            List<BusinessBelongingInfo> belongingInfoConditionList = belongingInfoService.findByLegionId(condition.getLegionId());
            if (!CollectionUtils.isEmpty(belongingInfoConditionList)) {
                groupIdList = belongingInfoConditionList.stream().map(BusinessBelongingInfo::getBusinessGroupId).distinct().collect(Collectors.toList());
                condition.setIdList(groupIdList);
            } else {
                condition.setIdList(Lists.newArrayList(9999999999999L));
                flag = true;
            }
        } else {
            condition.setIdList(Lists.newArrayList(9999999999999L));
            flag = true;
        }
        if ( !flag ) {
            if (StringUtils.isNotBlank(condition.getChannelCode()) || condition.getProjectId() != null || StringUtils.isNotBlank(condition.getRegionCode())) {
                RangeInfoCondition rangeInfoCondition = new RangeInfoCondition();
                rangeInfoCondition.setChannelCode(condition.getChannelCode());
                rangeInfoCondition.setProjectId(condition.getProjectId());
                rangeInfoCondition.setRegionCode(condition.getRegionCode());
                List<BusinessRangeInfo> businessRangeInfoList = rangeInfoService.rangeInfoList(rangeInfoCondition);
                if (!CollectionUtils.isEmpty(businessRangeInfoList)) {
                    List<Long> idList = businessRangeInfoList.stream().map(BusinessRangeInfo::getBusinessGroupId).distinct().collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(groupIdList)) {
                        groupIdList.retainAll(idList);
                        if (!CollectionUtils.isEmpty(groupIdList)) {
                            condition.setIdList(groupIdList);
                        } else {
                            condition.setIdList(Lists.newArrayList(9999999999999L));
                        }
                    } else {
                        condition.setIdList(idList);
                    }
                } else {
                    condition.setIdList(Lists.newArrayList(9999999999999L));
                }
            }
        }
    }
}
